package org.example.string;
/**
 * 有关String的面试题
 * @author youshang
 * @date 2022/03/27 17:37
 **/
public class StringTableInterview {

    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
    }

    private static void test1(){
        String s1 = "a" + "b" + "c";
        String s2 = "abc";

        System.out.println(s1 == s2); //结果：？
        System.out.println(s1.equals(s2)); //结果：？
    }

    private static void test2(){
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE"+"hadoop"; //编译器优化
        String s5 = s1+"hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//结果：？
        System.out.println(s3 == s5);//结果：？
        System.out.println(s3 == s6);//结果：？
        System.out.println(s3 == s7);//结果：？
        System.out.println(s5 == s6);//结果：？
        System.out.println(s5 == s7);//结果：？
        System.out.println(s6 == s7);//结果：？

        String s8 = s6.intern();
        System.out.println(s3 == s8);//结果：？
    }

    private static void test3(){
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        /* StringBuilder sb = new StringBuilder();
         * sb.append("a");
         * sb.append("b");
         * sb.toString(); - > 约等于 new String("ab");
         */
        String s4 = s1 + s2;
        System.out.println(s3 == s4);//结果：？
    }

    /**
     * 1. 字符串拼接操作不一定使用的是StringBuilder
     * 如果拼接符号左右两边都是字符串常量或常量引用，则仍然使用编译器优化，即非StringBuilder的方式。
     * 2. 针对于final修饰类、方法、基本数据类型、引用数据类型的量的结构时，能使用上final的时候就添加上。
     */
    private static void test4(){
        final String s1 = "a";
        final String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4);//结果：？
    }

    private static void test5(){
        final String s1 = "ab";
        final String s2 = "b";
        String s3 = "a"+s2; //ab

        System.out.println(s3==s1);//结果：？

        final String s4 = "a";
        String s5 = s4 + "b";
        System.out.println(s5 == s1);//结果：？

        String s6 = "b";
        String s7 = s4 + s6;
        System.out.println(s7 == s1);//结果：？
    }

    /*
     * 执行效率：通过StringBuilder的append()的方式添加字符串的效率要远高于使用String的字符串拼接方式
     * 详情：1. StringBuilder的append()方式：自始至终只创建了一个StringBuilder对象
     *          使用String字符串拼接方式：会创建过多的StringBuilder和String对象
     *      2.使用String字符串拼接方式：内存中由于创建了较多的StringBuilder和String对象,内存占用过大；如果进行GC 会花费而外的时间
     */
    private static void test6(){
        long start = System.currentTimeMillis();
        //add(); // 27973ms
        append(); // 10ms
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void add(){
        String str = "";
        for (int i = 0; i < 100000; i++) {
            //相当于每拼接一次都在创建 StringBuilder 、String
            str += i;
        }
    }

    private static void append(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            sb.append(i);
        }
    }
}
